package com.zbkj.front.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zbkj.common.constants.Constants;
import com.zbkj.common.enums.SmsTypeEnum;
import com.zbkj.common.exception.CommonException;
import com.zbkj.common.model.user.FeedbackInfo;
import com.zbkj.common.model.user.Partner;
import com.zbkj.common.model.user.User;
import com.zbkj.common.model.user.UserInvoice;
import com.zbkj.common.request.ChangePwdRequest;
import com.zbkj.common.request.SendSmsCodeRequest;
import com.zbkj.common.request.SmsCodeCheckRequest;
import com.zbkj.common.request.user.*;
import com.zbkj.common.response.product.ClientProductResponse;
import com.zbkj.common.response.user.ClientUserInvoiceResponse;
import com.zbkj.common.response.user.ClientUserLoginResponse;
import com.zbkj.common.token.FrontTokenComponent;
import com.zbkj.common.utils.CommonUtil;
import com.zbkj.common.utils.HttpUtils;
import com.zbkj.common.utils.RedisUtil;
import com.zbkj.front.service.OrderHandleService;
import com.zbkj.front.service.ProductHandleService;
import com.zbkj.front.service.UserHandleService;
import com.zbkj.service.service.SmsService;
import com.zbkj.service.service.SystemConfigService;
import com.zbkj.service.service.ValidateCodeService;
import com.zbkj.service.service.user.FeedbackInfoService;
import com.zbkj.service.service.user.PartnerService;
import com.zbkj.service.service.user.UserInvoiceService;
import com.zbkj.service.service.user.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @Auther:
 * @Date: 2024/7/5 15:14
 * @Description:
 */
@Slf4j
@Service
public class UserHandleServiceImpl implements UserHandleService {

    @Autowired
    private ValidateCodeService validateCodeService;
    @Autowired
    private UserService userService;
    @Autowired
    private FrontTokenComponent frontTokenComponent;
    @Autowired
    private SmsService smsService;
    @Autowired
    private PartnerService partnerService;
    @Autowired
    private UserInvoiceService userInvoiceService;
    @Autowired
    @Lazy
    private OrderHandleService orderHandleService;

    @Autowired
    private FeedbackInfoService feedbackInfoService;


    @Autowired
    private ProductHandleService productHandleService;

    @Override
    public ClientUserLoginResponse userLogin(ClientUserLoginRequest loginRequest) {
//        if(!validateCodeService.check(loginRequest.getKey(),loginRequest.getCode(),1)) {
//            throw new CommonException("验证码不正确");
//        }
        User user = userService.getUserByAccount(loginRequest.getAccount());
        //用户账户有效检查
        userService.userValidCheck(user);
        if(!user.getPwd().equals(CommonUtil.encryptPassword(loginRequest.getPwd(), CommonUtil.SERCRET_KEY))) {
            throw new CommonException("密码错误");
        }
        String token = frontTokenComponent.createToken(user.getId());
        ClientUserLoginResponse response = this.userLoginResponseBuild(user, token);
        return response;
    }

    public ClientUserLoginResponse userSmsCodeLogin(ClientUserSmscodeLoginRequest loginRequest) {
        smsService.checkValidateCode(loginRequest.getAccount(),loginRequest.getCode(), SmsTypeEnum.LOGIN_CODE);
        User user = userService.getUserByAccount(loginRequest.getAccount());
        //用户账户有效检查
        userService.userValidCheck(user);
        String token = frontTokenComponent.createToken(user.getId());
        ClientUserLoginResponse response = this.userLoginResponseBuild(user, token);
        return response;
    }

    @Override
    public void changePwd(ChangePwdRequest pwdRequest) {
        User user = userService.getLoginUserInfo();
        if(!user.getPwd().equals(CommonUtil.encryptPassword(pwdRequest.getPwd(), CommonUtil.SERCRET_KEY))) {
            throw new CommonException("旧密码错误");
        }
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setFirstLogin(1);
        updateUser.setPwd(CommonUtil.encryptPassword(pwdRequest.getNewPwd(),CommonUtil.SERCRET_KEY));
        userService.updateUserInfo(updateUser);
    }

    @Override
    public void endSmsCode(SendSmsCodeRequest smsCodeRequest) {
        SmsTypeEnum smsTypeEnum = SmsTypeEnum.getByType(smsCodeRequest.getSmsType());
        if(Objects.isNull(smsTypeEnum)) {
            throw new CommonException("不支持发送短信验证码类型");
        }
        if(smsTypeEnum.equals(SmsTypeEnum.FORGET_PASSWORD)) {
            User user = userService.getUserByAccount(smsCodeRequest.getPhone());
            if(Objects.isNull(user)) {
                throw new CommonException("账户信息不存在");
            }
        }
        smsService.sendCodeSms(smsCodeRequest.getPhone(),smsTypeEnum);
    }

    @Override
    public void smsCodeCheck(SmsCodeCheckRequest checkRequest) {
        SmsTypeEnum smsTypeEnum = SmsTypeEnum.getByType(checkRequest.getSmsType());
        if(Objects.isNull(smsTypeEnum)) {
            throw new CommonException("短信类型参数错误");
        }
        //手机号短信验证码检查
        smsService.checkValidateCode(checkRequest.getPhone(),checkRequest.getSmsCode(), smsTypeEnum);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void userRegiste(ClientUserRequest userRequest) {
//        smsService.checkValidateCode(userRequest.getPhone(),userRequest.getSmsCode(), SmsTypeEnum.REGISTE_CODE);
        //检查手机号是否存在
        boolean exist = userService.accountRepeatCheck(null, userRequest.getPhone());
        if(exist) {
            throw new CommonException("手机号已注册");
        }
        User user = new User();
        BeanUtils.copyProperties(userRequest,user);
        if(StringUtils.isNotBlank(userRequest.getInviteCode())) {
            Partner partner = partnerService.getByIviteCode(userRequest.getInviteCode());
            if(Objects.isNull(partner)) {
                throw new CommonException("邀请码不存在");
            }
            user.setInviterId(partner.getId());
        }
        user.setAccount(user.getPhone());
        user.setPwd(CommonUtil.encryptPassword(userRequest.getPwd(), CommonUtil.SERCRET_KEY));
        List<ClientProductResponse> pro_list = productHandleService.list();

        // 提取试用包的 trialDays
        int trialDays = 0;
        for (ClientProductResponse product : pro_list) {
            if (product.getProductType() == 2 && "试用包".equals(product.getProductName())) {
                trialDays = product.getTrialDays();
                break; // 找到试用包后退出循环
            }
        }
        // 计算试用包到期时间
        if (trialDays > 0) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date()); // 设置当前时间
            calendar.add(Calendar.HOUR_OF_DAY, trialDays * 24); // 增加对应天数的小时数
            user.setTrialExpire(calendar.getTime()); // 设置试用包到期时间
        } else {
            user.setTrialExpire(null); // 如果没有试用天数，设置试用包到期时间为 null
        }

        user.setDataval(0L);
        //保存注册用户信息
        boolean rowFlag =userService.userSaveOrUpdate(user);
        if(!rowFlag) {
            throw new CommonException("用户注册保存失败");
        }
        //用户注册赠送年卡处理
//        orderHandleService.registeGiftYearCardHandle(user);
//        orderHandleService.registeGiftTryCardHandle(user);
    }

    @Override
    public void forgetPwdSave(UserForgetPwdRequest pwdRequest) {
        smsService.checkValidateCode(pwdRequest.getPhone(),pwdRequest.getSmsCode(), SmsTypeEnum.FORGET_PASSWORD);
        User user = userService.getUserByAccount(pwdRequest.getPhone());
        if(Objects.isNull(user)) {
            throw new CommonException("账户信息不存在");
        }
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setPwd(CommonUtil.encryptPassword(pwdRequest.getPwd(),CommonUtil.SERCRET_KEY));
        userService.updateUserInfo(updateUser);
    }

    @Override
    public ClientUserLoginResponse getUser(HttpServletRequest request) {
        String token = frontTokenComponent.getToken(request);
        Long userId = frontTokenComponent.getUserId();
        User user = userService.getUserById(userId);
        if(Objects.isNull(user) || user.getDeleteFlag() == 1) {
            throw new CommonException("用户信息不存在");
        }



        return this.userLoginResponseBuild(user, token);
    }

    @Override
    public ClientUserInvoiceResponse getUserInvoice() {
        User user = userService.getLoginUserInfo();
        if(Objects.isNull(user) || user.getDeleteFlag() == 1) {
            throw new CommonException("用户信息不存在");
        }
        UserInvoice userInvoice = userInvoiceService.getInvoiceByUserId(user.getId());
        ClientUserInvoiceResponse response = new ClientUserInvoiceResponse();
        if(Objects.nonNull(userInvoice)) {
            BeanUtils.copyProperties(userInvoice, response);
        }
        return response;
    }

    @Override
    public void userInvoiceSave(ClientUserInvoiceRequest invoiceRequest) {
        User user = userService.getLoginUserInfo();
        if(Objects.isNull(user) || user.getDeleteFlag() == 1) {
            throw new CommonException("用户信息不存在");
        }
        UserInvoice userInvoice = userInvoiceService.getInvoiceByUserId(user.getId());
        if(Objects.nonNull(userInvoice)) {
            throw new CommonException("发票信息已存在，不能修改");
        }
        if(invoiceRequest.getInvoiceType() == 2) {
            //增值税专用发票 --必填参数检查
            invoiceRequest.type2ParamCheck();
        }
        UserInvoice newInvoice = new UserInvoice();
        BeanUtils.copyProperties(invoiceRequest, newInvoice);
        newInvoice.setUserId(user.getId());
        userInvoiceService.save(newInvoice);
    }

    @Override
    public void userAuthVerifyOpt(UserAuthVerifyRequest authVerifyRequest) {
        Long userId = frontTokenComponent.getUserId();
        User user = userService.getUserById(userId);
        userService.userValidCheck(user);

        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setRealName(authVerifyRequest.getRealName());
        updateUser.setIdCard(authVerifyRequest.getIdCard());
        if(authVerifyRequest.getOptType().intValue() == 0) {
            updateUser.setPhone(user.getPhone());
        } else {
            if(StringUtils.isBlank(authVerifyRequest.getNewPhone())) {
                throw new CommonException("换绑手机号不能为空");
            }
            if(user.getPhone().equals(authVerifyRequest.getNewPhone())){
                throw new CommonException("换绑手机号不能与当前手机号相同");
            }
            //换绑手机号验证码检查
            smsService.checkValidateCode(authVerifyRequest.getNewPhone(),authVerifyRequest.getNewSmsCode(), SmsTypeEnum.AUTH_VERIFY_CODE);
            if(userService.accountRepeatCheck(userId, authVerifyRequest.getNewPhone())) {
                throw new CommonException("换绑手机号已被注册");
            }
            updateUser.setAccount(authVerifyRequest.getNewPhone());
            updateUser.setPhone(authVerifyRequest.getNewPhone());
        }
        //进行实名认证检查
        authRealNameVerifyReq(userId,updateUser.getPhone(),updateUser.getRealName(),updateUser.getIdCard());
        updateUser.setAuthStatus(1);
        userService.updateUserInfo(updateUser);
    }

    @Override
    public void userInfoModify(ClientUserModifyRequest userModifyRequest) {
        Long userId = frontTokenComponent.getUserId();
        User user = userService.getUserById(userId);
        userService.userValidCheck(user);
        User updateUser = new User();
        BeanUtils.copyProperties(userModifyRequest,updateUser);
        updateUser.setId(user.getId());
        userService.updateUserInfo(updateUser);
    }

    @Override
    public void feedbackSave(ClientFeedbackSaveRequest feedbackSaveRequest) {
        Long userId = frontTokenComponent.getUserId();
        FeedbackInfo feedbackInfo = new FeedbackInfo();
        feedbackInfo.setFbType(feedbackSaveRequest.getFbType());
        feedbackInfo.setUserId(userId);
        feedbackInfo.setFbContext(feedbackSaveRequest.getFbContext());
        feedbackInfoService.save(feedbackInfo);
    }


    private void authRealNameVerifyReq(Long userId, String phone, String rname, String idCard) {
        if(StringUtils.isBlank(phone)) {
            throw new CommonException("实名认证缺少手机号参数");
        }
        if(StringUtils.isBlank(rname)) {
            throw new CommonException("实名认证缺少姓名参数");
        }
        if(StringUtils.isBlank(idCard)) {
            throw new CommonException("实名认证缺少身份证号参数");
        }
        Map<String, String> querys = new HashMap<String, String>();
        JSONObject jsonObject = null;
        String host = "https://mobilecert.market.alicloudapi.com";
        String path = "/mobile3MetaSimple";
        String method = "GET";
        String appcode = "42fb891cab9f47d3a8a91d8536004352";
        HashMap<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        querys.put("identifyNum", idCard);
        querys.put("userName", rname);
        querys.put("mobile", phone);
        try {
            String result = HttpUtils.doGet(host, path, method, headers, querys);
            if(StringUtils.isBlank(result)) {
                throw new CommonException("实名认证请求未获得结果");
            }
            jsonObject = JSON.parseObject(result);
            Integer code  = Integer.valueOf(String.valueOf(jsonObject.get("code")));
            if(code == 200) {
                String bizCode = (String) jsonObject.getObject("data",Map.class).get("bizCode");
                if (!StringUtils.equals(bizCode,"1") ){ //匹配不成功
                    throw new CommonException("实名认证失败，信息不匹配");
                }
            } else{
                throw new CommonException("实名认证失败");
            }
        } catch (CommonException ce) {
            throw ce;
        }catch (Exception e){
            log.error("authRealNameVerify-userId:{}-阿里云实名认证请求error:",userId,e);
            throw new CommonException("实名认证请求失败");
        } finally {
            log.info("authRealNameVerify-userId:{}-param:{}-result:{}",userId,JSON.toJSONString(querys),jsonObject);
        }
    }

    /**
     * 登录用户响应对象组装
     * @param user
     * @param token
     * @return
     */
    private ClientUserLoginResponse userLoginResponseBuild(User user, String token) {
        ClientUserLoginResponse response = new ClientUserLoginResponse();
        BeanUtils.copyProperties(user, response);
        response.setTotalDataval(user.getCardDataval() + user.getDataval());
        response.setToken(token);
        response.setSysTime(System.currentTimeMillis());


        // 获取当前时间
        Calendar now = Calendar.getInstance();
        Date currentDate = now.getTime();

        // 判断年卡失效时间和试用包到期时间
        if (user.getCardExpire() != null && user.getCardExpire().after(currentDate)) {
            // 年卡失效时间在当前时间之后，设置用户身份为2
            response.setUserIdentity(2);
        } else if (user.getTrialExpire() != null && user.getTrialExpire().after(currentDate)) {
            // 试用包到期时间在当前时间之后，设置用户身份为1
            response.setUserIdentity(1);
        } else {
            // 否则设置用户身份为0
            response.setUserIdentity(0);
        }

        return response;
    }

    @Override
    public String userLoginByName(String account) {
        User user = userService.getUserByAccount(account);
        //用户账户有效检查
        userService.userValidCheck(user);
        return frontTokenComponent.createToken(user.getId());
    }

    @Override
    public void userRegisteByAccountPwd(ClientUserRegionRequest userRequest) {
        //检查手机号是否存在
        boolean exist = userService.accountRepeatCheck(null, userRequest.getPhone());
        if(exist) {
            throw new CommonException("手机号已注册");
        }
        User user = new User();
        BeanUtils.copyProperties(userRequest,user);

        user.setAccount(user.getPhone());
        user.setPwd(CommonUtil.encryptPassword(userRequest.getPwd(), CommonUtil.SERCRET_KEY));
        //保存注册用户信息
        boolean rowFlag =userService.userSaveOrUpdate(user);
        if(!rowFlag) {
            throw new CommonException("用户注册保存失败");
        }
    }
}
